
/**
 * 
 * @author David
 *
 */
package Server;
import java.util.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author David
 * @version $Revision: 1.0 $
 */
public class Server implements java.io.Serializable{
	
	//for getting time stamps
	/**
	 * used for getting timestamps
	 */
	private final Calendar cal = Calendar.getInstance();

	/**
	 * Field StartDate.
	 */
	public Date startDate;

	/**
	 * Field objOut.
	 */
	private ObjectOutputStream objOut;	//to come later = new ObjectOutputStream(new FileOutputStream(filename));

	/**
	 * Field fout.
	 */
	
	private FileOutputStream fout;
	
	/**
	 * create output stream for user list
	 */
	static Writer listOut = null;
	Reader listIn = null;
	String fileName = "userList.txt";
    File file = new File(fileName);
	//for logging
	/**
	 * Field admin.
	 */
	
	private final Admin admin;

	/**
	 * Field fileOutputStream.
	 */
	private FileOutputStream fileOutputStream;
	
	/**
	 * Server gets initialized
	 */
	
	private UserHandler uHandler = new UserHandler();
	
	protected Server(){
		startDate = cal.getTime();
		
		admin = new Admin("Administrator", "Password");
		try {
			listOut = new BufferedWriter(new FileWriter(file));
			System.out.println("userList created");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (!file.exists()){
	    	try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    	System.out.println("created userList.txt");
	    }
		//put writer on new file
		try {
			listOut = new BufferedWriter(new FileWriter(file));
			listIn = new BufferedReader(new FileReader(file));
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		
		////**********************************////
		////	Server Client Communication
		////**********************************////
		ServerSocket serverSocket = null;
		try {
		    serverSocket = new ServerSocket(4444);
		} catch (IOException e) {
		    System.out.println("Could not listen on port: 4444");
		    System.exit(-1);
		}
		
		Socket clientSocket = null;
		try {
		    clientSocket = serverSocket.accept();
		} catch (IOException e) {
		    System.out.println("Accept failed: 4444");
		    System.exit(-1);
		}
		
		try {
			PrintWriter out = new PrintWriter(
			        clientSocket.getOutputStream(), true);
			
			BufferedReader in = new BufferedReader(
			          new InputStreamReader(
			              clientSocket.getInputStream()));
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		////**********************************////
		/////************************************/////
	}
	
	/**
	 * 
	 * @return String
	 */
	public String toString(){
		final String str = "";
		return str;
	}
	
	public static void createUser(String user, String pass, String access){
		try {
			listOut.write(user + "," + pass + "," + access + "\n");
			listOut.flush();
			System.out.println("printed to userList");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * Saves user as a data file on logout
	 * creates file with user id as name
	 * @param u the user to be saved
	 */
	public void saveUser(User u){
		final int uid = u.getID();
		final String filename = Integer.toString(uid) + ".ser";
		File userFile = new File(filename);
		if(!userFile.exists()){
			try {
				userFile.createNewFile();
				System.out.println(filename + " created");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("saving " + filename);
		try{
			OutputStream outFile = new FileOutputStream( filename );
			OutputStream buffer = new BufferedOutputStream( outFile );
			ObjectOutput output = new ObjectOutputStream( buffer );
			////////////////////////
			ObjectOutput out = new ObjectOutputStream(new FileOutputStream("test.ser"));
		    out.writeObject(u);
		    out.flush();
		    out.close();
		    System.out.println("here");
		    ////////////////////////
		    /*
			try{
				//objOut = new ObjectOutputStream(fout);
				objOut.writeObject(u);
				objOut.flush();
			}
			finally{
				objOut.close();
			}
			*/
		}
		catch(IOException ex){
			System.exit(0);
		}
		}
		/*
		try{
			
			fileOutputStream = new FileOutputStream(filename);
			fout = fileOutputStream;
			OutputStream outFile = new FileOutputStream( "quarks.ser" );
		    OutputStream buffer = new BufferedOutputStream( outFile );
		    ObjectOutput output = new ObjectOutputStream( buffer );
			try{
				//objOut = new ObjectOutputStream(fout);
				objOut.writeObject(u);
			}
			finally{
				objOut.close()
			}
		}
		catch(FileNotFoundException e){
			//log error
			System.out.println("File not found");
			System.exit(0);
		}
	}
	*/
	
	/**
	 * returns user after un-serializing
	 * @param id user ID
	
	 * @return User matching id */
	public User getPatient(int id){
		final User use = new User("Empty", "password");
		/*String filename = Integer.toString(id) + ".data";
		try{
		FileInputStream fin = new FileInputStream(filename);
		}
		catch(FileNotFoundException e){
			System.out.println("File Not Found");
			//change message to log
			
		}*/
		
		return use;
	}

	/**
	 * creates a new user
	 * @param n String
	 * @param id int
	
	 * @return Patient */
	public Patient createPatient(String n, String password){
		//change later
		int id = 0;
		//set id
		final Patient use = new Patient(n, password);
		use.setID(id);
		//log creation
		admin.log("Created user " + id);
		return use;
	}
	
	/**
	 * Method createDoctor.
	 * @param n String
	 * @param id int
	
	 * @return Doctor */
	public Doctor createDoctor(String n, String password){
		//change later
		int id = 1;
		//set id
		final Doctor use = new Doctor(n, password);
		use.setID(id);
		//log creation
		admin.log("Created user " + id);
		return use;
	}
	
	/**
	 * Method createNurse.
	 * @param n String
	 * @param id int
	
	 * @return Nurse */
	public Nurse createNurse(String n, String password){
		//change later
		int id = 2;
		//set id
		final Nurse use = new Nurse(n, password);
		use.setID(id);
		//log creation
		admin.log("Created user " + id);
		return use;
	}

	/**
	 * deletes user object
	 * @param u User to be deleted
	 */
	private void deleteUser(User u){
		//fill in after serialize
		final int id = u.getID();
		final String filename = Integer.toString(id) + ".data";
		final File userFile = new File(filename);
		userFile.delete();
		
		admin.log("Deleted User " + id);
		System.out.println("User Deleted");
	}

	/**
	 * updates user by deleting old and creating new
	 * @param u old user that is being deleted
	 * @param n name update
	 * @param id ID of new user
	
	 * @return Patient */
	private Patient updatePatient(Patient u, String n, int id){
		//delete user
		this.deleteUser(u);
		//create new user, updating the field selected
		final Patient pat = createPatient(n, u.getpassword());
		//delete old user
		
		//admin.log("Updated user " + pat.getID());
		System.out.println("User Updated");
		return pat;
	}
	
	/**
	 * Method updateDoctor.
	 * @param u Doctor
	 * @param n String
	 * @param id int
	
	 * @return Doctor */
	private Doctor updateDoctor(Doctor u, String n, int id){
		//delete user
		this.deleteUser(u);
		//create new user, updating the field selected
		final Doctor d = this.createDoctor(n, u.getpassword());
		//delete old user
		
		admin.log("Updated user " + d.getID());
		//System.out.println("User Updated");
		return d;
	}
	
	/**
	 * Method updateNurse.
	 * @param u Nurse
	 * @param n String
	 * @param id int
	
	 * @return Nurse */
	private Nurse updateNurse(Nurse u, String n, int id){
		//delete user
		this.deleteUser(u);
		//create new user, updating the field selected
		final Nurse nu = createNurse(n, u.getpassword());
		//delete old user
		
		admin.log("Updated user " + nu.getID());
		//System.out.println("User Updated");
		return nu;
	}
}

	/**
	 * Method main.
	 * @param args String[]
	 */
/*
	public static void main(String [] args){
		final Server s= new Server();
		System.out.println("Server Created");
		Patient pat;
		Doctor d;
		Nurse nurse;
		//Create and update a patient
		createUser("Name", "Password", "Patient");
		createUser("blah", "rabble", "Doctor");
		pat = s.createPatient("Patient", "password");
		System.out.println("User: " + pat.getName() + " " + Integer.toString(pat.getID()));
		//s.saveUser(pat);
		final Patient newUser = s.createPatient("Patient Update", "password");
		pat = s.updatePatient(pat, newUser.getName(), newUser.getID());
		System.out.println("User: " + pat.getName() + " " + Integer.toString(pat.getID()));
		
		//Create treatment
		final Date date1 = new Date();
		final Treatments tr1 = new Treatments("Dr. Walters", "Lucy", "Headache",
				01234, 56789, 100, 100,
				70, 100, 100, date1);
		final Date date2 = new Date();
		final Treatments tr2 = new Treatments("Dr. Hatcher", "Lucy", "Headache",
				01234, 56789, 100, 100,
				70, 100, 100, date2);
		pat.getMedicalhistory().canAddTreatment(tr1);
		pat.getMedicalhistory().canAddTreatment(tr2);
		//Read treatment
		if(pat.getMedicalhistory().isEmpty()){
			System.out.println("Medical History is Empty");
		}
		else {
			for(Treatments tr : pat.getMedicalhistory().getTreatmentList()){
				tr.toPrint();
			}
		}
		
		//Create doctor order
		final DoctorsOrders docOrder = new DoctorsOrders( "prescription", "labWork", "followUp",
				"otherInstr");
		pat.getMedicalhistory().getTreatmentList().getLast().setDocOrders(docOrder);
		//Read doctor order
		System.out.println(pat.getMedicalhistory().getTreatmentList().getLast().getDocOrders().toString());
		//Update doctor order
		if (pat.getMedicalhistory().getTreatmentList().getLast().isHasDocOrders()) {
			System.out.println("DoctorsOrders exists.");
		}
		else {
			pat.getMedicalhistory().getTreatmentList().getLast().getDocOrders().setPrescription("new prescription");
		}
		System.out.println(pat.getMedicalhistory().getTreatmentList().getLast().getDocOrders().toString());
		//Delete doctor order
		pat.getMedicalhistory().getTreatmentList().getLast().setHasDocOrders(false);
		if (pat.getMedicalhistory().getTreatmentList().getLast().isHasDocOrders()) {
			System.out.println("DoctorsOrders exists.");
		}
		else {
			pat.getMedicalhistory().getTreatmentList().getLast().getDocOrders().setPrescription("new prescription");
		}
		System.out.println(pat.getMedicalhistory().getTreatmentList().getLast().getDocOrders().toString());
		//Delete treatment
		pat.getMedicalhistory().canRemoveTreatment(tr1);
		if(pat.getMedicalhistory().isEmpty()){
			System.out.println("Medical History is Empty");
		}
		else {
			for(Treatments tr : pat.getMedicalhistory().getTreatmentList()){
				tr.toPrint();
			}
		}	
		//Create and update a doctor
		d = s.createDoctor("Doctor", "password");
		System.out.println("User: " + d.getName() + " " + Integer.toString(d.getID()));
		final Patient newDoc = s.createPatient("Doctor Update", "password");
		//s.saveUser(d);
		d = s.updateDoctor(d, newDoc.getName(), newDoc.getID());
		System.out.println("User: " + d.getName() + " " + Integer.toString(d.getID()));
		//Create and update Nurse
		nurse = s.createNurse("Nurse", "password");
		System.out.println("User: " + nurse.getName() + " " + Integer.toString(nurse.getID()));
		final Patient newNurse = s.createPatient("Nurse Update", "password");
		//s.saveUser(nurse);
		nurse = s.updateNurse(nurse, newNurse.getName(), newNurse.getID());
		System.out.println("User: " + nurse.getName() + " " + Integer.toString(nurse.getID()));
		//delete users
		s.deleteUser(pat);
		s.deleteUser(d);
		s.deleteUser(nurse);
		
		
		
		
		final Appointments appt = new Appointments(2011, 3, 18, 9, 30, "headache", "Dr. Walker");
		final AppointmentBook ab = new AppointmentBook();
		final Appointments appt1 = new Appointments(2011, 3, 18, 10, 30, "headache", "Dr. Walker");
		ab.canAddAppt(appt);
		ab.canAddAppt(appt1);
		for(DailyAppointment da : ab.getApptBook()){
			if(ab.getApptBook().isEmpty()){
				System.out.println("Empty");
			}
			else {
				for(Appointments ap : da.getApptList()){
					System.out.println(ap.getGc().toString());
				}
			}
		}
		
		System.out.println("Appointments added");
		ab.canRemoveAppt(appt1);
		for(DailyAppointment da : ab.getApptBook()){
			if(ab.getApptBook().isEmpty()){
				System.out.println("Empty");
			}
			else {
				for(Appointments ap : da.getApptList()){
					System.out.println(ap.getGc().toString());
				}
			}
		}
		final Appointments appt2 = new Appointments(2010, 2, 4, 10, 30, "idk", "lol");
		System.out.println("Appointment removed");
		
		if(ab.canRemoveAppt(appt2))				//expected false value
			System.out.println("Does not exist");
		
		System.out.println("");
		System.out.println("Invoice:");
		appt.setPrice(40);
		appt.setpName("George");
		final Invoice iv = new Invoice(appt);
		System.out.println(iv.toString());
		
	}

}

*/
